package org.easyelf.springmvc.core.base.impl;

import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.easyelf.springmvc.core.Constants;
import org.easyelf.springmvc.core.base.BaseMapper;
import org.easyelf.springmvc.core.base.BaseModel;
import org.easyelf.springmvc.core.util.InstanceUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

/**
 * @Title: BaseServiceImpl
 * @Description: 业务逻辑层基类，继承基类后必须配置CacheConfig(cacheNames="")
 * @Package: org.easyelf.springmvc.core.base with IntelliJ IDEA
 * @User: RehngaO
 * @Date: 2017-02-07
 * @Time: 下午7:51
 */

public class BaseServiceImpl<T extends BaseModel> extends ServiceImpl implements ApplicationContextAware {

	private final Logger logger = LoggerFactory.getLogger(this.getClass());

	@Autowired
	protected BaseMapper<T> mapper;
	protected ApplicationContext applicationContext;

	public void setApplicationContext(ApplicationContext applicationContext) {
		this.applicationContext = applicationContext;
	}

//	/**
//	 * 传统分页查询
//	 * @param params	分页参数，包括pageNum页号、pageSize页行、orderBy排序字段
//	 * @return
//	 */
//	public static Page<Long> getPage(Map<String, Object> params) {
//		Integer current = 1;
//		Integer size = 10;
//		String orderBy = "id";
//		if (DataUtil.isNotEmpty(params.get("pageNum"))) {
//			current = Integer.valueOf(params.get("pageNum").toString());
//		}
//		if (DataUtil.isNotEmpty(params.get("pageSize"))) {
//			size = Integer.valueOf(params.get("pageSize").toString());
//		}
//		if (DataUtil.isNotEmpty(params.get("orderBy"))) {
//			orderBy = (String) params.get("orderBy");
//			params.remove("orderBy");
//		}
//		if (size == -1) {
//			return new Page<Long>();
//		}
//		Page<Long> page = new Page<Long>(current, size, orderBy);
//		page.setAsc(false);
//		return page;
//	}
//
//	/**
//	 * 根据ID分页查询(默认类型T)
//	 * @param ids	ids参数
//	 * @return	Page<T>对象
//	 */
//	public Page<T> getPage(Page<Long> ids) {
//		if (ids != null) {
//			Page<T> page = new Page<T>(ids.getCurrent(), ids.getSize());
//			page.setTotal(ids.getTotal());
//			List<T> records = InstanceUtil.newArrayList();
//			for (Long id : ids.getRecords()) {
//				records.add(this.queryById(id));
//			}
//			page.setRecords(records);
//			return page;
//		}
//		return new Page<T>();
//	}
//
//	/**
//	 * 根据ID分页查询(默认类型T)
//	 * @param ids	ids参数
//	 * @return	Page<Map<String, Object>>对象
//	 */
//	public Page<Map<String, Object>> getPageMap(Page<Long> ids) {
//		if (ids != null) {
//			Page<Map<String, Object>> page = new Page<Map<String, Object>>(ids.getCurrent(), ids.getSize());
//			page.setTotal(ids.getTotal());
//			List<Map<String, Object>> records = InstanceUtil.newArrayList();
//			for (Long id : ids.getRecords()) {
//				records.add(InstanceUtil.transBean2Map(this.queryById(id)));
//			}
//			page.setRecords(records);
//			return page;
//		}
//		return new Page<Map<String, Object>>();
//	}
//
//	/**
//	 * 根据ID分页查询(cls返回类型Class)
//	 * @param ids	ids参数
//	 * @return	Page<K>对象
//	 */
//	public <K> Page<K> getPage(Page<Long> ids, Class<K> cls) {
//		if (ids != null) {
//			Page<K> page = new Page<K>(ids.getCurrent(), ids.getSize());
//			page.setTotal(ids.getTotal());
//			List<K> records = InstanceUtil.newArrayList();
//			for (Long id : ids.getRecords()) {
//				T t = this.queryById(id);
//				K k = InstanceUtil.to(t, cls);
//				records.add(k);
//			}
//			page.setRecords(records);
//			return page;
//		}
//		return new Page<K>();
//	}
//
//	/**
//	 * 根据ID查询(默认类型T)
//	 * @param ids	ids参数
//	 * @return	list
//	 */
//	public List<T> getList(List<Long> ids) {
//		List<T> list = InstanceUtil.newArrayList();
//		if (ids != null) {
//			for (Long id : ids) {
//				list.add(this.queryById(id));
//			}
//		}
//		return list;
//	}
//
//	/**
//	 * 根据ID查询(cls返回类型Class)
//	 * @param ids	ids参数
//	 * @return	Page<K>对象
//	 */
//	public <K> List<K> getList(List<Long> ids, Class<K> cls) {
//		List<K> list = InstanceUtil.newArrayList();
//		if (ids != null) {
//			for (Long id : ids) {
//				T t = this.queryById(id);
//				K k = InstanceUtil.to(t, cls);
//				list.add(k);
//			}
//		}
//		return list;
//	}

//	public Page<T> query(Map<String, Object> params) {
//		Page<Long> page = getPage(params);
//		page.setRecords(mapper.selectIdPage(page, params));
//		return getPage(page);
//	}
//
//	public Page<Map<String, Object>> queryMap(Map<String, Object> params) {
//		Page<Long> page = getPage(params);
//		page.setRecords(mapper.selectIdPage(page, params));
//		return getPageMap(page);
//	}
//
//	public List<T> queryList(Map<String, Object> params) {
//		List<Long> ids = mapper.selectIdPage(params);
//		List<T> list = getList(ids);
//		return list;
//	}
//
//	protected <P> Page<P> query(Map<String, Object> params, Class<P> cls) {
//		Page<Long> page = getPage(params);
//		page.setRecords(mapper.selectIdPage(page, params));
//		return getPage(page, cls);
//	}

	/**
	 * 逻辑删除
	 * 如果操作isLock、isDel、gmtCreate、gmtModified，请使用该方法
	 * @param id
	 */
	@Transactional
	public void del(Long id) {
		try {
			T record = this.queryById(id);
			record.setIsLock(0);
			record.setIsDel(0);
			record.setGmtCreate(new Date());
			record.setGmtModified(new Date());
			mapper.updateById(record);
//			TODO
//			CacheUtil.getCache().set(getCacheKey(id), record);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			throw new RuntimeException(e.getMessage(), e);
		}
	}

	/**
	 * 物理删除
	 * @param id
	 */
	@Transactional
	public void delete(Long id) {
		try {
			mapper.deleteById(id);
//			TODO
//			CacheUtil.getCache().del(getCacheKey(id));
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			throw new RuntimeException(e.getMessage(), e);
		}
	}

	@Transactional
	public T update(T record) {
		try {
			record.setGmtModified(new Date());
			if (record.getId() == null) {
				record.setGmtCreate(new Date());
				mapper.insert(record);
			} else {
				String lockKey = getClass().getName() + record.getId();
//				if (CacheUtil.getLock(lockKey)) {
//					try {
						T org = queryById(record.getId());
						T update = InstanceUtil.getDiff(org, record);
						update.setId(record.getId());
						mapper.updateById(update);
//					} finally {
//						CacheUtil.unlock(lockKey);
//					}
//				}
			}
			record = mapper.selectById(record.getId());
//			CacheUtil.getCache().set(getCacheKey(record.getId()), record);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			throw new RuntimeException(e.getMessage(), e);
		}
		return record;
	}

	@Transactional
	@SuppressWarnings("unchecked")
	public T queryById(Long id) {
		try {
//			String key = getCacheKey(id);
//			T record = (T) CacheUtil.getCache().get(key);
//			if (record == null) {
			T record = mapper.selectById(id);
//				CacheUtil.getCache().set(key, record);
//			}
			return record;
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			throw new RuntimeException(e.getMessage(), e);
		}
	}

	/** 获取缓存键值 */
	protected String getCacheKey(Object id) {
		String cacheName = null;
		CacheConfig cacheConfig = getClass().getAnnotation(CacheConfig.class);
		if (cacheConfig == null || cacheConfig.cacheNames() == null || cacheConfig.cacheNames().length < 1) {
			cacheName = getClass().getName();
		} else {
			cacheName = cacheConfig.cacheNames()[0];
		}
		return new StringBuilder(Constants.CACHE_NAMESPACE).append(cacheName).append(":").append(id).toString();
	}
}
